[AD] Scalaアプリケーションの開発・保守は合同会社ミルクソフトにお任せください
コンピュータの制御用の文字や、プログラムの構文上重要な文字については、ほんらいの文字のままでは記述することができません。
エスケープ(escape)とは、このような文字を別の文字として置き換えることによって、文字列として伝えることができるようにすることをいいます。
この記事では、文字列をエスケープする方法を解説します。
エスケープ対象となる文字の一覧
Scalaのエスケープ規則ははJavaと共通です。
JavaやScalaにおいては、バックスラッシュ(\
)でエスケープすることによって以下の文字を記述することができます。
ここでエスケープ対象となる文字を一覧にしておきます。
名称 | 英語名 | 表示 | エスケープ後 | 備考 |
---|---|---|---|---|
バックスラッシュ | backslash | \ | \\ | エスケープ文字 |
引用符 | quotation | ' | \' | |
二重引用符 | double quotation | " | \" | |
改行文字 | Line Feed | \n | Unix系OSにおける改行 | |
復帰文字 | Carriage Return | \r | ||
行末文字 | End of Line | \r\n | Windows等における改行 | |
タブ文字 | Tab | \t | ||
バックスペース | backspace | \b | ||
改ページ | form feed | \f |
生文字リテラル("""
)でエスケープなしに文字列を書く
さて、これはエスケープをする方法に関する記事なのですが、あらかじめエスケープせずに済む方法について触れておきますね。
Scalaにおいてエスケープが必要な文字を書きたい場合には、生文字リテラル(raw string literal)を使うのが便利です。
特段の事情がなければこちらを使うのがいいでしょう。
生文字リテラルとは、ダブルクォーテーション1つ("
)ではなく、ダブルクォーテーション3つ("""
)で囲って文字列を宣言する方法のことをいいます。
生文字リテラルを使うと、本来エスケープが必要なはずの文字が含まれていたとしても、見たままの文字列をエスケープせずにそのまま出力することができます。
val rawStr = """this is "escaped" string.""" println(rawStr)
出力は以下のとおりです。
ダブルクォーテーションという文字は、普通の文字列リテラルの中で使うにはエスケープが必要です。
しかしここでは生文字リテラルを使っているので、エスケープせず記述したそのままの文字列が出力されていることがわかります。
this is "escaped" string.
ただし、今回はエスケープ方法について解説する記事ですので、これ以降は上記のようなコードを普通の文字列リテラルで記述する方法について紹介します。
個別の文字をエスケープするにはバックスラッシュ(\
)を使う
上述の通り、バックスラッシュ(\
)を使用することによって文字列リテラルの中にエスケープの必要な文字を記述することができます。
次の例ではダブルクォーテーションを普通の文字列リテラルの中で使用するためにエスケープしています。
val str = "this is \"escaped\" string." println(str)
出力は以下のようになります。
期待通り、ダブルクォーテーションも含めて文字列が出力できています。
this is "escaped" string.
文字列をエスケープするにはCommons Textを使う
さて「文字列がエスケープの必要な文字を含んでいるためにエスケープしたい」という場合にはどうすべきでしょうか。
文字列をエスケープするには、Apache Commons Textというライブラリを使用しましょう。
Commons Textには、文字列をエスケープしたり復元したりするためのStringEscapeUtils
というクラスがあります。
Javaの規則に則った変換を行うメソッドに加えて、JSONやHTML、XMLなどをエスケープするメソッドも用意されています。
Commons Textを使用するための準備をする
Commons Textを使用するには、Commons Textを依存性に追加する必要があります。
build.sbtのライブラリ依存性に、Commons Textに関する行を追加すればOKです。
build.sbtlibraryDependencies ++= Seq( "org.apache.commons" % "commons-text" % "1.8" )
これでCommons Textが使えるようになります(sbtのリロードを忘れずに!)
escapeJava
メソッドを使って文字列をエスケープする
まずはStringEscapeUtils
クラスをインポートします。
そしてescapeJava
メソッドにエスケープしたい文字列を渡します。
import org.apache.commons.text.StringEscapeUtils val str = """this string will be "escaped".""" val escaped = StringEscapeUtils.escapeJava(str) println(escaped)
出力結果は以下のようになります。
期待通り、文字列がエスケープされているのがわかりますね。
this string will be \"escaped\".
unescapeJava
メソッドを使ってエスケープされた文字列を復元する
エスケープされた文字列を復元するには、unescapeJava
メソッドを使用します。
こちらもまずStringEscapeUtils
クラスをインポートして、次にunescapeJava
メソッドにエスケープしたい文字列を渡します。
import org.apache.commons.text.StringEscapeUtils val str = """this string will be \"unescaped\".""" val unescaped = StringEscapeUtils.unescapeJava(str) println(unescaped)
出力は以下のようになります。
すでにエスケープされた状態の文字列がエスケープされていない文字列に復元されたのがわかります。
this string will be "unescaped".